// 路由
package router

import (
	"gitee.com/xgotool/backend-framework-template/app/crontab"
	"gitee.com/xgotool/backend-framework-template/app/middlewares"
	"gitee.com/xgotool/backend-framework-template/app/queue"
	"gitee.com/xgotool/backend-framework-template/app/web"
	"gitee.com/xiaoyutab/xgotool/individual/xginplus"
	"github.com/gin-gonic/gin"
)

var r *gin.Engine

// 定义一个临时结构体来存储路由信息
type roles struct {
	mps map[string]func(*xginplus.Context) *xginplus.Response
}

// 添加路由
func (c *roles) Append(mps ...map[string]func(*xginplus.Context) *xginplus.Response) {
	for _, mp := range mps {
		for k, v := range mp {
			c.mps[k] = v
		}
	}
}

// 导出r变量（router路由）
//
//	mod	gin框架的运行模式
func RouterExplode(mod string) *gin.Engine {
	gin.SetMode(mod)
	// 经测试，若路由声明放到init里面的话，会在setMode前生效，导致gin模式配置失败
	if r == nil {
		r = gin.Default()
		// 避免因域名前缀导致的路由未找到问题
		// PS：此处可以使用NGINX路由转发重写解决，但配置起来较为麻烦，此处暂不考虑
		// 分页中间件、CORS中间件和用户授权中间件
		r.Use(middlewares.Cors)
		// 配置项
		xginplus.SetDefault(
			xginplus.WithSuccessData(func(c any) (int, any) {
				return 200, gin.H{
					"code":    0,
					"request": c,
				}
			}), // 成功默认项信息
			xginplus.WithSuccessPage(func(c *xginplus.Context, count int64, data any, ext gin.H) (int, any) {
				dat := gin.H{
					"code": 0,
					"request": gin.H{
						"data":  data,
						"total": count,
					},
				}
				if len(ext) > 0 {
					dat["request"].(gin.H)["ext"] = ext
				}
				return 200, dat
			}), // 成功分页数据的配置项信息
			xginplus.WithJitter(true),
			xginplus.WithLimitOriginal(-1),
		) // 设置默认项
		r.NoRoute(xginplus.Convert(web.NotFond))  // 404路由未找到
		r.NoMethod(xginplus.Convert(web.NotFond)) // 404-路由未找到

		// 注册路由
		r.Use(middlewares.UserInfo)                         // 提取token信息
		r.Use(middlewares.Log)                              // 日志记录中间件
		xginplus.ConvertMap(r.Group(""), nologinRouter())   // 无需登录的路由
		r.Use(middlewares.MustLogin)                        // 登陆验证中间件
		xginplus.ConvertMap(r.Group(""), mustloginRouter()) // 需要登录的路由
		r.Use(middlewares.MustAdmin)                        // 后台权限验证中间件
		xginplus.ConvertMap(r.Group(""), mustadminRouter()) // 需要管理员权限的路由

		// 路由加载完成，开始加载队列、定时任务等
		queue.Listen() // 队列初始化监听
		crontab.Init() // 定时任务初始化
	}
	return r
}
